import React, { useEffect, useState, Key } from 'react'
import {
  Card,
  Row,
  Col,
  Tree,
  Tag,
  Pagination,
  Table,
  Button,
  message,
} from 'antd'
import type { DataNode, TreeProps } from 'antd/es/tree'
import type { ColumnsType } from 'antd/es/table'
import { useParams } from 'react-router-dom'
import {
  IdepList,
  IbookingRuleList,
  IscheduleList,
} from '@api/hospital/hospitalList/model/hospitalListTypes'
import {
  reqGetDepartmentList,
  reqGetScheduleRules,
  reqGetScheduleList,
} from '@api/hospital/hospitalList'

import './hospitalSchedule.css'

let depcode: string // 存储当前科室的编码
export default function HospitalSchedule() {
  const hoscode = useParams().hoscode as string
  // 存储当前医院的所有科室数据
  const [depList, setDepList] = useState<IdepList>([])
  // 存储所有一级科室的depcode的数组
  const [keyList, setKeyList] = useState<Key[]>([])

  // 分页相关的状态
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(5)
  const [total, setTotal] = useState(50)

  // 排班规则的状态
  const [scheduleRule, setScheduleRule] = useState<IbookingRuleList>([])

  // 排班详情的状态
  const [scheduleList, setScheduleList] = useState<IscheduleList>([])

  // 面包屑相关的状态
  const [hosname, setHosname] = useState('')
  const [depname, setDepname] = useState('')
  const [workDate, setWorkDate] = useState('')

  useEffect(() => {
    async function fetch() {
      // 获取当前医院的科室数据
      const { depcode: dcode, depname } = await getDepList()
      depcode = dcode
      setDepname(depname)
      // 由于getDepList是异步函数,所以返回值是promise.当这个函数中所有代码执行完毕之后,promise就会变成成功
      const workDate = await getScheduleRules(page, pageSize, depcode)

      // 获取排班详情
      getScheduleList(workDate)
    }
    fetch()
  }, [])

  // 获取当前医院科室数据的函数
  async function getDepList() {
    const result = await reqGetDepartmentList(hoscode as string)
    // result中的每一个对象里面,都没有disabled属性,但是我们的需求是禁用一级科室, 就必须给一级科室的数据对象中添加disabled属性,值为true
    result.forEach((item) => {
      item.disabled = true
    })

    setDepList(result)

    // 把所有科室数据中的一级科室的depcode存储起来
    setKeyList(
      result.map((item) => {
        return item.depcode
      })
    )

    // 要返回专科里面的多发性硬化的depcode
    return {
      depcode: result[0].children[0].depcode,
      depname: result[0].children[0].depname,
    }
  }

  // 获取指定科室的排班规则数据的函数
  async function getScheduleRules(
    page: number,
    pageSize: number,
    depcode: string
  ) {
    const result = await reqGetScheduleRules(page, pageSize, hoscode, depcode)
    setTotal(result.total)
    setScheduleRule(result.bookingScheduleList)
    setHosname(result.baseMap.hosname)
    setWorkDate(
      result.bookingScheduleList[0]
        ? result.bookingScheduleList[0].workDate
        : ''
    )
    // 返回wordDate,用于组件挂载时,获取排班详情
    return result.bookingScheduleList[0]
      ? result.bookingScheduleList[0].workDate
      : ''
  }

  // 获取排班详情的函数
  async function getScheduleList(workDate: string) {
    if (!workDate) return setScheduleList([])
    const result = await reqGetScheduleList(hoscode, depcode, workDate)
    setScheduleList(result)
  }

  // 点击某个科室时触发的事件
  const onSelect = async (selectedKeys: any, info: any) => {
    // console.log('selected', selectedKeys, info)
    // 1. 修改状态depname
    setDepname(info.node.depname)
    // 2. 修改全局变量depcode
    depcode = selectedKeys[0]
    // 3. 获取排班规则并渲染
    setPage(1)
    const workDate = await getScheduleRules(1, pageSize, depcode)
    // 4. 获取排班详情并渲染
    getScheduleList(workDate)
  }

  const columns: ColumnsType<any> = [
    {
      title: '序号',
      render: (a: any, b: any, index: number) => {
        return index + 1
      },
      align: 'center',
    },
    {
      title: '职称',
      dataIndex: 'title',
    },
    {
      title: '号源时间',
      dataIndex: 'workDate',
    },
    {
      title: '可预约数',
      dataIndex: 'availableNumber',
    },
    {
      title: '剩余预约数',
      dataIndex: 'reservedNumber',
    },
    {
      title: '挂号费(元)',
      dataIndex: 'amount',
    },
    {
      title: '擅长技能',
      dataIndex: 'skill',
    },
  ]

  // 计算左侧科室树结构的高度
  // DOM和BOM阶段: offsetLeft, offsetTop, offsetWidth,offsetHeight, scrollTop,scrollLeft,scrollWidth, scrollHeight, clientWidth, clientHeight 必须记住
  //   const treeHeight = 当前页面可视区的高度 - 其他的一些高度
  const treeHeight =
    document.documentElement.clientHeight - 64 - 34 - 24 * 2 - 22 - 14
  return (
    <Card>
      <p>
        选择：{hosname} / {depname} / {workDate}
      </p>
      {/* gutter表示当前这一行中的col,相隔20px */}
      <Row gutter={20}>
        <Col span={5}>
          <div className="treeWrap" style={{ height: treeHeight }}>
            <Tree
              //   checkable //控制树结构是否有复选框
              //   defaultExpandedKeys={['0-0-0', '0-0-1']} // 默认展示项的key值
              //   defaultSelectedKeys={['0-0-0', '0-0-1']}
              //   defaultCheckedKeys={['0-0-0', '0-0-1']}
              onSelect={onSelect} // 点击树结构中的某一项触发的事件
              //   onCheck={onCheck} // 点击复选框
              treeData={depList as any} // 树结构要展示的数据
              // 默认tree组件,要渲染的是treeData数据中的title和key. 但是我们的数据中没有title和key,对应的是depname和depcode. 所以通过fieldNames这个属性,告诉Tree组件,要渲染的是treeData中的depname和depcode
              fieldNames={{
                title: 'depname',
                key: 'depcode',
              }}
              expandedKeys={keyList}
            />
          </div>
        </Col>
        <Col span={19}>
          {scheduleRule.map((item) => {
            return (
              <Tag
                key={item.workDate}
                color={item.workDate === workDate ? 'green' : ''}
                onClick={() => {
                  // 点击Tag,让选择的日期变化,并且让指定tag高亮
                  setWorkDate(item.workDate)
                  // 获取排班详情
                  getScheduleList(item.workDate)
                }}
              >
                <div>
                  {item.workDate} {item.dayOfWeek}
                </div>
                <div>
                  {item.availableNumber} / {item.reservedNumber}
                </div>
              </Tag>
            )
          })}

          <Pagination
            current={page}
            total={total}
            pageSize={pageSize}
            showSizeChanger={true}
            style={{ marginTop: 20, marginBottom: 20 }}
            onChange={async (page, pageSize) => {
              setPage(page)
              setPageSize(pageSize)
              // 获取排班规则
              const workDate = await getScheduleRules(page, pageSize, depcode)
              // 获取排班详情
              getScheduleList(workDate)
            }}
          ></Pagination>

          <Table
            columns={columns}
            dataSource={scheduleList}
            bordered
            rowKey={'id'}
            pagination={false} //表格不显示分页器
          ></Table>
          <Button style={{ marginTop: 20 }}>返回</Button>
        </Col>
      </Row>
    </Card>
  )
}
